package com.hatic.money;

import java.util.Map;

import org.jxstar.dao.DaoParam;
import org.jxstar.service.BusinessObject;
import org.jxstar.util.DateUtil;
import org.jxstar.util.MapUtil;

/**
 * 投资计划备案处理。
 *
 * @author TonyTan
 * @version 1.0, 2011-10-16
 */
public class PlanMemoBO extends BusinessObject {
	private static final long serialVersionUID = 1L;

	/**
	 * 自动汇总父计划的金额
	 * @param parentId
	 * @return
	 */
	public String sumMoney(String parentId) {
		updateSum(parentId);
		
		return _returnSuccess;
	}
	
	/**
	 * 转为非上报国家局计划的投资计划：
	 * 1、必须是新申报的计划，不能是结转的计划；
	 * 2、如果是虚拟包，则删除虚拟包、清除包内子计划中的父亲对象ID与编码，修改up_comp=0；
	 * 3、如果是大计划或普通计划，新申报的大计划应该没有子计划，直接修改up_comp=0；
	 * 4、修改计划状态为待授权：plan_status=31
	 * @param planIds
	 * @return
	 */
	public String toNotUp(String[] planIds) {
		if (planIds == null || planIds.length == 0) {
			setMessage("没有选择投资计划！");
			return _returnFaild;
		}
		
		for (int i = 0, n = planIds.length; i < n; i++) {
			if (!toNotUp(planIds[i])) {
				return _returnFaild;
			}
		}
		
		return _returnSuccess;
	}
	
	//转为非上报国家局计划的投资计划
	private boolean toNotUp(String planId) {
		String sql = "select is_turn, bao_type, plan_code from money_plan where plan_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(planId);
		Map<String,String> mp = _dao.queryMap(param);
		if (mp.isEmpty()) {
			setMessage("没有找到选择的投资计划！");
			return false;
		}
		
		String is_turn = mp.get("is_turn");
		String bao_type = mp.get("bao_type");
		String plan_code = mp.get("plan_code");
		
		if (is_turn.equals("1")) {
			setMessage("【{0}】是结转投资计划，不能转为非上报国家局计划！", plan_code);
			return false;
		}
		
		if (bao_type.equals("1")) {//虚拟包
			//修改包内子计划状态
			String usql = "update money_plan set plan_parentid = '', plan_parentcode = '', up_comp = '0', plan_status = '31', bao_type = '0' where plan_parentid = ?";
			param = _dao.createParam(usql);
			param.addStringValue(planId);
			_dao.update(param);
			//删除虚拟包计划
			usql = "delete from money_plan where plan_id = ?";
			param = _dao.createParam(usql);
			param.addStringValue(planId);
			_dao.update(param);
		} else {
			String usql = "update money_plan set up_comp = '0', plan_status = '31' where plan_id = ?";
			param = _dao.createParam(usql);
			param.addStringValue(planId);
			_dao.update(param);
		}
		
		return true;
	}
	
	/**
	 * 新创建的计划包，提交检验：
	 * 没有子计划的包也不能提交；
	 * 创建投资计划包提交时把子计划的总投资与年度投资金额汇总到计划包中；
	 * 更新计划的状态；
	 * 
	 * @param planIds
	 * @return
	 */
	public String newbao(String[] planIds) {
		if (planIds == null || planIds.length == 0) {
			setMessage("没有选择投资计划包！");
			return _returnFaild;
		}
		
		for (int i = 0, n = planIds.length; i < n; i++) {
			if (!hasSubPlan(planIds[i])) {
				setMessage("当前计划包没选择子计划，不能提交！");
				return _returnFaild;
			}
			
			if (!updateSum(planIds[i])) {
				return _returnFaild;
			}
			
			updateStatus(planIds[i], "25");
			updateSubStatus(planIds[i], "25");
		}
		
		return _returnSuccess;
	}
	
	/**
	 * 国家局备案上报，检查内容：
	 * 1、年度投资金额不能大于总投资，两者都不能为零；
	 * 2、修改状态为“备案中”；
	 * 
	 * @param planIds
	 * @return
	 */
	public String memoup(String[] planIds) {
		if (planIds == null || planIds.length == 0) {
			setMessage("没有选择投资计划包！");
			return _returnFaild;
		}
		
		for (int i = 0, n = planIds.length; i < n; i++) {
			if (!memoup(planIds[i])) {
				return _returnFaild;
			}
			
			memoupStatus(planIds[i]);
			updateSubStatus(planIds[i], "26");
		}
		
		return _returnSuccess;
	}
	
	/**
	 * 国家局备案下达，检查内容：
	 * 1、年度投资金额不能大于总投资，两者都不能为零；
	 * 2、修改状态为“待实施”31；
	 * 
	 * @param planIds
	 * @return
	 */	
	public String memodo(String[] planIds) {
		if (planIds == null || planIds.length == 0) {
			setMessage("没有选择投资计划包！");
			return _returnFaild;
		}
		
		for (int i = 0, n = planIds.length; i < n; i++) {
			if (!memoup(planIds[i])) {
				return _returnFaild;
			}
			
			//修改状态为待授权
			memodoStatus(planIds[i]);
			updateSubStatus(planIds[i], "31");
			
			//虚拟包与大计划都需要授权
			//updateBaoStatus(planIds[i]);
		}
		
		return _returnSuccess;
	}
	
	/**
	 * 备案否决
	 * @param planIds
	 * @return
	 */
	public String memocancel(String[] planIds) {
		if (planIds == null || planIds.length == 0) {
			setMessage("没有选择投资计划包！");
			return _returnFaild;
		}
		
		for (int i = 0, n = planIds.length; i < n; i++) {
			if (!memocancel(planIds[i])) {
				setMessage("投资计划备案否决失败！");
				return _returnFaild;
			}
			
			updateSubStatus(planIds[i], "91");
		}
		
		return _returnSuccess;
	}
	
	//更新计划包的金额
	public boolean updateSum(String planId) {
		Map<String,String> mpSum = sumPlan(planId);
		
		//取包属性，如果是大计划，则不更新“预计总投资”
		String baoType = getBaoType(planId);
		
		double plan_money = tonum(mpSum.get("plan_money"));
		double year_money = tonum(mpSum.get("year_money"));
		_log.showDebug("------------------投资计划合计金额为：" + plan_money + ";" + year_money);
		
		if (!checkmoney(plan_money, year_money)) return false;
		
		String usql = "update money_plan set year_money = ? where plan_id = ?";
		if (baoType.equals("1")) {
			usql = "update money_plan set plan_money = ?, year_money = ? where plan_id = ?";
		}
		_log.showDebug("---------------更新投资计划金额的SQL=" + usql);
		
		DaoParam uparam = _dao.createParam(usql);
		if (baoType.equals("1")) {
			uparam.addDoubleValue(Double.toString(plan_money));
		}
		
		uparam.addDoubleValue(Double.toString(year_money));
		uparam.addStringValue(planId);
		if (!_dao.update(uparam)) {
			setMessage("更新计划包的金额出错！");
			return false;
		}
		
		return true;
	}
	
	//效验总投资与年度投资值的合法性
	private boolean checkmoney(double plan_money, double year_money) {
		if (plan_money == 0) {
			setMessage("当前计划包中的子计划预计总投资合计为0，不能提交！");
			return false;
		}
		if (year_money == 0) {
			setMessage("当前计划包中的子计划年度投资合计为0，不能提交！");
			return false;
		}
		if (plan_money < year_money) {
			setMessage("当前计划包中的子计划年度投资大于预计总投资，不能提交！");
			return false;
		}
		
		return true;
	}
	
	//字符串转换为数字
	private double tonum(String num) {
		if (num == null || num.length() == 0) return 0;
		
		return Double.parseDouble(num);
	}
	
	//检查是否有子计划
	private boolean hasSubPlan(String planId) {
		String sql = "select count(*) from money_plan where plan_parentid = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(planId);
		Map<String,String> mpCnt = _dao.queryMap(param);
		
		return MapUtil.hasRecord(mpCnt);
	}
	
	private boolean memoup(String planId) {
		String sql = "select money_type2, bao_type, plan_money, year_money from money_plan where plan_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(planId);
		Map<String,String> plandata = _dao.queryMap(param);
		if (plandata.isEmpty()) {
			setMessage("当前计划没有找到，不能提交！");
			return false;
		}
		
		String money_type2 = plandata.get("money_type2");
		if (money_type2.length() == 0) {
			setMessage("当前计划的国家局项目类别为空，不能提交！");
			return false;
		}
		
		String baoType = plandata.get("bao_type");
		//普通计划
		if (baoType.equals("0")) {
			double plan_money = tonum(plandata.get("plan_money"));
			double year_money = tonum(plandata.get("year_money"));
			_log.showDebug("------------------投资计划合计金额为：" + plan_money + ";" + year_money);
			
			if (!checkmoney(plan_money, year_money)) return false;
		} else if (baoType.equals("1")) {
			if (!updateSum(planId)) return false;
		} 
		
		if (baoType.equals("6") || baoType.equals("7")) {
			setMessage("当前计划为子计划，不能提交！");
			return false;
		}
		
		return true;
	}
	
	//投资计划备案否决
	private boolean memocancel(String planId) {
		String sql = "update money_plan set up_edate = ?, up_result = '1', plan_status = '91' where plan_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addDateValue(DateUtil.getToday());
		param.addStringValue(planId);
		
		return _dao.update(param);
	}
	
	//投资计划国家局备案上报，修改状态
	private boolean memoupStatus(String planId) {
		String sql = "update money_plan set up_sdate = ?, up_result = '0', plan_status = '26' where plan_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addDateValue(DateUtil.getToday());
		param.addStringValue(planId);
		
		return _dao.update(param);
	}
	
	//投资计划国家局备案下达，修改状态
	private boolean memodoStatus(String planId) {
		String sql = "update money_plan set up_edate = ?, up_result = '0', plan_status = '31' where plan_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addDateValue(DateUtil.getToday());
		param.addStringValue(planId);
		
		return _dao.update(param);
	}
	
	//修改投资计划状态
	private boolean updateStatus(String planId, String status) {
		String sql = "update money_plan set plan_status = ? where plan_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(status);
		param.addStringValue(planId);
		
		return _dao.update(param);
	}
	
	//修改投资计划包的状态为待实施
	/*private boolean updateBaoStatus(String planId) {
		String sql = "update money_plan set plan_status = '41' where bao_type = '1' and plan_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(planId);
		
		return _dao.update(param);
	}*/
	
	//修改子投资计划状态
	private boolean updateSubStatus(String parentId, String status) {
		String plancode = getParentCode(parentId);
		
		String sql = "update money_plan set plan_status = ?, plan_parentcode = ? where plan_parentid = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(status);
		param.addStringValue(plancode);
		param.addStringValue(parentId);
		
		return _dao.update(param);
	}
	
	//汇总子计划的金额
	private Map<String,String> sumPlan(String parentId) {
		String sql = "select sum(plan_money) as plan_money, sum(year_money) as year_money " +
				"from money_plan where plan_parentid = ? and plan_status < '91'";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(parentId);
		return _dao.queryMap(param);
	}
	
	//取投资计划编码
	private String getParentCode(String planId) {
		String sql = "select plan_code from money_plan where plan_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(planId);
		
		Map<String, String> mpData = _dao.queryMap(param);
		return mpData.get("plan_code");
	}
	
	//取投资计划包属性
	private String getBaoType(String planId) {
		String sql = "select bao_type from money_plan where plan_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(planId);
		
		Map<String, String> mpData = _dao.queryMap(param);
		return mpData.get("bao_type");
	}
}
